/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package deatax.display;

import javax.media.opengl.GL2;

/**
 *
 * @author nrechten
 */
public class Tween {

    protected final static float init_speed = 0.0003f;
    protected Vector3f target;
    protected Vector3f current;
    protected Vector3f remaining;
    public float accel = 0.0001f;
    public float max_speed = 0.005f;
    public float speed = init_speed;
    protected Vector3f temp;
    protected Vector3f dir;
    long last_draw = 0;
    protected TweenListener listener;

    public Tween(float[] target) {
        this(target[0], target[1], target[2]);
    }

    public Tween(float[] target, float[] current) {
        this(target[0], target[1], target[2], current[0], current[1], current[2]);
    }

    public Tween(float target_x, float target_y, float target_z) {
        current = new Vector3f(target_x, target_y, target_z);
        setTarget(target_x, target_y, target_z);
    }

    public Tween(float target_x, float target_y, float target_z, float current_x, float current_y, float current_z) {
        current = new Vector3f(current_x, current_y, current_z);
        setTarget(target_x, target_y, target_z);
    }

    public void setTarget(float target_x, float target_y, float target_z) {
        target = new Vector3f(target_x, target_y, target_z);
//        System.out.println("Target = " + target.toString());
        dir = new Vector3f(target);
        dir.sub(current);
        remaining = new Vector3f(dir);
        dir.normalize();
//        System.out.println(dir.toString());
    }

    public void setTarget(float[] target) {
        setTarget(target[0], target[1], target[2]);
    }

    public void setListener(TweenListener listener) {
        this.listener = listener;
    }

    public void step() {
        if (testFinished()) {
            return;
        }
        //Calc the time since the last step
        if(last_draw == 0){ last_draw = System.currentTimeMillis(); }
        float scale = (System.currentTimeMillis() - last_draw);///1000f;
        last_draw = System.currentTimeMillis();

        //System.out.println(scale);

        if (speed < max_speed) {
            speed += accel;
            if (speed > max_speed) {
                speed = max_speed;
            }
            
        }

        temp = new Vector3f(dir);
        temp.scale(speed * scale);

        float l = remaining.length();
        remaining.sub(temp);

        if (remaining.length() > l) {
            current = target;
            if (listener != null) {
                listener.onTweenFinished(this);
            }
        } else {
            current.add(temp);
        }
        //Check if
    }

    public void resetSpeed() {
        speed = init_speed;
        last_draw = 0;
        System.out.println(speed);
    }

    public boolean testFinished() {

        if (current == target || remaining.length() <= 0) {
            current = target;
            return true;
        }
        return false;
    }

    public void translate(GL2 gl) {
        gl.glTranslated(current.x, current.y, current.z);
    }

    public void itranslate(GL2 gl) {
        gl.glTranslated(-current.x, -current.y, -current.z);
    }
    
    public void scale(GL2 gl) {
        gl.glScalef(current.x, current.y, current.z);
    }

    public void iscale(GL2 gl) {
        gl.glScalef(1/current.x, 1/current.y, 1/current.z);
    }
    
    public void rotate(GL2 gl){
        gl.glRotatef(current.x, 1, 0, 0);
        gl.glRotatef(current.y, 0, 1, 0);
        gl.glRotatef(current.z, 0, 0, 1);
    }
    
    public void irotate(GL2 gl){
        gl.glRotatef(current.z, 0, 0, 1);
        gl.glRotatef(current.y, 0, 1, 0);
        gl.glRotatef(current.x, 1, 0, 0);
    }

    void forceAddPos(float x, float y, int z) {
        current.x += x;
        current.y += y;
        current.z += z;

        if (current != target) {
            target.x += x;
            target.y += y;
            target.z += z;
        }
    }

    @Override
    public String toString() {
        return "Tween currently: " + current.toString() + ", Target: " + target.toString() + ", Dir: " + dir.toString() + ", Remaining:" + remaining.toString();
    }

    public Vector3f getCurrent() {
        return current;
    }
    
    
}
